home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / m2 / cat3src / cat / protokol.i < prev    next >
Text File  |  1997-10-26  |  58KB  |  1,703 lines

  1. IMPLEMENTATION MODULE Protokoll;
  2.  
  3. (*==============================================================*
  4.  * Modul:               Protokollmodul fr Cat                  *
  5.  * Autor:               Johannes G”ttker-Schnetmann             *
  6.  * erstellt am:         M„rz 1991                               *
  7.  * letzte Žnderung am:  01.12.1992                              *
  8.  * Version:             1.0                                     *
  9.  * Interne Version:     V#0002                                  *
  10.  *==============================================================*
  11.  
  12.  Dieses Modul macht Cat zu einem Xacc-Hauptprogramm der Stufe 0. Aužerdem 
  13.  werden vom AV/VA-Protokoll die sinnvollen Msgs untersttzt.
  14.  
  15.  Weiterhin ist hier das Protokoll fr den WatchDog verwirklicht:
  16.  Ein WatchDog-Acc wird erkannt an seinem Namen "WATCHDOG", der beim AV- und
  17.  XAcc-Protokoll erkannt wird. Sobald er erkannt wurde, bekommt er eine Msg
  18.  [HelloWatchDog, CatGreetings, Version, (CatVersionString)]. Er kann dann 
  19.  [HelloWatchDog, enable/disableWatchDog] verschicken und bekommt jeweils
  20.  eine [HelloWatchDog, CatAffirm, on/off] als Best„tigung. Aužerdem bekommt
  21.  er eine Msg CatTerminate am Programmende von Cat. Ist der WatchDog
  22.  w„hrend des Einfgens von Msgs angeschaltet, dann wird er jeweils mit
  23.  einem [HelloWatchDog, CatAsk, ptr] gefragt, ob diese Msg passieren darf.
  24.  Er kann mit einem [HelloWatchDog, CatAccept/CatForget/CatFiltered] antworten.
  25.  Im ersten Fall wird die Msg bernommen, im zweiten Fall wird sie verworfen und
  26.  im dritten Fall wird bei ihr das "gefiltert"-Flag gesetzt.
  27.  
  28.  Dieses WatchDog-Protokoll macht unter MultiTOS mit Memoryprotection vorraussichtlich
  29.  Probleme, da der WatchDog nach der bisherigen Implementation auf Speicher von 
  30.  Cat zugreift! Wahrscheinlich mssen wir und dafr noch etwas einfallen lassen.
  31.  (shared-memory..)
  32.  
  33.  Die Erl„uterung des erweiterten Protokolls steht weiter unten. "HelloWatchDog"
  34.  hat jetzt die allgemeinere Bedeutung "CatMsg".
  35.  Insbesondere die Erkennung des WatchDogs soll in einer der n„chsten Versionen
  36.  nach M”glichkeit auf die Methode des erweiterten Protokolls umgestellt werden.
  37.  
  38.  *----------------------------------------------------------------------------
  39.  * Datum    Vers. Autor  Žnderung (Arbeitsbericht)                            
  40.  *----------------------------------------------------------------------------
  41.  * 01.02.92 0002  JGS    Protokollerweiterung fr Steueraccs
  42.  * 24.05.93 0003  DS     Erweiterung um MultiTasking-Untersttzung
  43.  *                       CAT XACC-Versionsnummer ge„ndert auf 20H
  44.  *----------------------------------------------------------------------------
  45.  *)
  46.  
  47.  
  48. FROM SYSTEM          IMPORT ADR, ADDRESS, WORD, CADR, CALLSYS, TSIZE;
  49. FROM WdwManager      IMPORT NewWindowIsTop, WindowIsClosed, WdwDoesDragDrop,
  50.                             WdwDDGetExts, WdwDDAcceptData, WdwDDWriteData,
  51.                             HandleEvent;
  52. FROM UserInformation IMPORT UserBLK;
  53. FROM Void            IMPORT v;
  54. FROM CatTypes        IMPORT Str255Ptr, String255, BigTextPtr;
  55. FROM CatGlobal       IMPORT multiTask, multiTOS, magIx, magIxVer;
  56. FROM Storage         IMPORT ALLOCATE, DEALLOCATE;
  57. IMPORT FileNames;
  58. IMPORT Block;
  59. IMPORT Strings;
  60. IMPORT StrConv;
  61.  
  62. IMPORT data;
  63. IMPORT grin;
  64.  
  65. IMPORT MagicAES;
  66. IMPORT MagicStrings;
  67. IMPORT mtAppl;
  68. IMPORT mtAlerts;
  69. IMPORT mtCommand;
  70. IMPORT MagicDOS;
  71. IMPORT MagicCookie;
  72. IMPORT Mintbind;
  73. IMPORT ConvertDate;
  74.  
  75. CONST
  76.  
  77.   appName    = 'CAT     '+0C+'XDSC'+0C+'1MausTausch-Programm'+0C+'2DC'+0C+0C;
  78.   watchDog   = 'WATCHDOG';
  79.   watchFound = 0815H;
  80.   
  81. (* CalcClock *)
  82.   CALCLOCK  = 100;
  83.   CALCLOCK_OK = 101;
  84.  
  85. (* XAcc: *)
  86.  
  87.   ACC_ID    = 400H;
  88.   ACC_OPEN  = 401H;
  89.   ACC_CLOSE = 402H;
  90.   ACC_ACC   = 403H;
  91.   ACC_EXIT  = 404H;
  92.   ACC_ACK   = 500H;
  93.   ACC_TEXT  = 501H;
  94.   ACC_KEY   = 502H;
  95.   
  96. (* PC-Help Protokoll *)
  97.   AC_HELP   = 1025;         (* message to DA *)
  98.   AC_REPLY  = 1026;         (* message from DA *)
  99.   AC_VERSION= 1027;         (* Ask DA for version *)
  100.   AC_COPY   = 1028;         (* Ask DA to copy screen to clipboard *)
  101.  
  102. (* AV/VA-Protokoll *)
  103.  
  104.   AV_PROTOKOLL     = 4700H;
  105.   VA_PROTOSTATUS   = 4701H;
  106.  
  107. (* not used *)
  108.   AV_GETSTATUS     = 4703H;
  109.   AV_STATUS        = 4704H;
  110.   VA_SETSTATUS     = 4705H;
  111. (*----------*)
  112.  
  113.   AV_SENDKEY       = 4710H;
  114.   VA_START         = 4711H;
  115.  
  116. (* not used *)
  117.   AV_ASKFILEFONT   = 4712H;
  118.   VA_FILEFONT      = 4713H;
  119.   AV_ASKCONFONT    = 4714H;
  120.   VA_CONFONT       = 4715H;
  121.   AV_ASKOBJECT     = 4716H;
  122.   VA_OBJECT        = 4717H;
  123.   AV_OPENCONSOLE   = 4718H;
  124.   VA_CONSOLEOPEN   = 4719H;
  125. (*----------*)
  126.  
  127.   AV_OPENWIND      = 4720H;
  128.   VA_WINDOPEN      = 4721H;
  129.   AV_STARTPROG     = 4722H;
  130.   VA_PROGSTART     = 4723H;
  131.   AV_ACCWINDOPEN   = 4724H;
  132.  
  133. (* not used *)
  134.   VA_DRAGACCWIND   = 4725H; (* NOCH, wichtig fr Kommandozeile an Takeoff *)
  135. (*----------*)
  136.  
  137.   AV_ACCWINDCLOSED = 4726H;
  138.   AV_PATH_UPDATE   = 4730H;
  139.  
  140. (* Bits *)
  141.  
  142.   xAV_SENDKEY       = 0;
  143.   xAV_ASKFILEFONT   = 1;
  144.   xAV_ASKCONFONT    = 2; (* auch xAV_OPENCONSOLE *)
  145.   xAV_ASKOBJECT     = 3;
  146.   xAV_OPENWIND      = 4;
  147.   xAV_STARTPROG     = 5;
  148.   xAV_ACCWINDOPEN   = 6; (* auch xAV_ACCWINDCLOSED *)
  149.   xAV_STATUS        = 7; (* auch AV_GETSTATUS *)
  150.  
  151.  
  152. (*## Cat-Protokoll ################################################*)
  153.  
  154. (* GutenTag *)
  155.   HelloWatchDog = 8000H;
  156.   CatMsg        = 8000H;
  157.   ExtCatMsg     = 8001H;
  158.  
  159.   Cat2FiltMsg   = 8002H;        (* Fr Laberfilter-Anbindung *)
  160.   CatProtoMsg   = 8003H;        (* Neues CAT-Protokoll *)
  161.  
  162.   (* Sub-Opcodes fr CatMsg *)
  163.  
  164.   enableWatchDog  = 0;
  165.   disableWatchDog = 1;
  166.   CatAffirm       = 2;
  167.  
  168.   CatAsk          = 3;
  169.   CatAccept       = 4;
  170.   CatForget       = 5;
  171.   CatGreetings    = 6;
  172.   CatTerminate    = 7;
  173.   CatFiltered     = 8;
  174.  
  175.  
  176.   WdwManager     = 9;
  177.   CatWinInfo     = 10;
  178.   CatWhatsIn     = 11;
  179.   CatPosition    = 12;
  180.   CatNewMess     = 13;
  181.   CatInform      = 14;
  182.   CatWinDirty    = 15;
  183.  
  184.   CatProtoVersion   = 1; (* Das ist Version Nummer 1 *)
  185.   
  186.   (* Sub-Opcodes fr Cat2FiltMsg *)
  187.   
  188.   FilterStandard    = 0;        (* Default *)
  189.   
  190.   (* Sub-Opcodes fr neues CAT-Protokoll *)
  191.   (* Doku: Siehe NEWPROTO.TXT            *)
  192.   
  193.   CAT_ACK           = 0;
  194.   CAT_ERROR         = 1;
  195.   CAT_LOGIN         = 2;
  196.   CAT_LOGOFF        = 3;
  197.   CAT_SENDER        = 4;
  198.   CAT_RNAME         = 5;
  199.   CAT_RECEIVER      = 6;
  200.   CAT_MAUS_ID       = 7;
  201.   CAT_MSG_ID        = 8;
  202.   CAT_MAUS_REF      = 9;
  203.   CAT_REF           = 10;
  204.   CAT_TOPIC         = 11;
  205.   CAT_BOX           = 12;
  206.   CAT_GATE          = 13;
  207.   CAT_DIST          = 14;
  208.   CAT_MIME          = 15;
  209.   CAT_STATUS        = 16;
  210.   CAT_FOLLOWUP      = 17;
  211.   CAT_REPLYTO       = 18;
  212.   CAT_TEXT          = 19;
  213.   CAT_MSG_DATE      = 20;
  214.   CAT_STATUS_DATE   = 21;
  215.   CAT_GROUP         = 22;
  216.   CAT_ORG_TEXT      = 23;
  217.   CAT_IS_OWN        = 24;
  218.   CAT_UNIQUE_ID     = 25;
  219.   CAT_REAL_SENDER   = 26;
  220.   CAT_WDW_NAME      = 27;
  221.   
  222.   CAT_NEW_MSG       = 100;
  223.   CAT_TERMINATE     = 101;
  224.   
  225. (* 
  226. mess[0] = 0x8002;
  227. mess[1] = apId;  (* 0 *)
  228. mess[2] = oversize; (* 0 *)
  229. mess[3] = length of filter data;   (* must not be 0 *)
  230. mess[4] + mess[5] = pointer to filter data;
  231. mess[6] + mess[7] = unused (* must be 0 *)
  232. *)
  233.  
  234.  
  235.  
  236. (* --------------------------------------------------------------------------
  237. Also dann: 
  238. mess[0] ist bei allen Msgs 0x8000, d.h. 8000 hexadezimal.
  239. mess[1] ist ja einfach die Applikation-ID des Absenders;
  240. mess[2] ist wie blich die šberl„nge der Nachricht, also die Gesamtl„nge 
  241. der Nachricht - 16. CB = CatBaum als Arbeitsname.
  242.  
  243. mess[3],mess[4]
  244. CatGreetings
  245.  6              CB->Cat Anmeldung bei Cat (evtl. kommt in mess[5] noch eine 
  246.                 Unterscheidung, ob es sich um einen WatchDog handelt, also 
  247.                 dort am besten eine Null eintragen). Fr etwas anderes als
  248.                 einen Watchdog darf in mess[5] keine 0 stehen.
  249.  6      version Cat-CB  Anmeldung angekommen, Protokoll-Versionsnummer zum 
  250.                 berprfen als Anlage. (evtl. mess[5,6,7] Cat-Versionsnummer 
  251.                 als String? - erstmal nicht!)
  252.  
  253. WdwManager
  254.  9      art     ACC->Cat, Anforderung der offenen Fenster, mess[5+6] 
  255.                 enthalten eine Adresse fr den Buffer, in den CAT 
  256.                 die Information hineinschreibt. mess[7] enth„lt die 
  257.                 Maximalanzahl an Fenstern, die in den Buffer passen 
  258.                 (pro Eintrag ein Integer, also 2 Byte)
  259.                 "art" enth„lt die Art der Fenster, die geliefert 
  260.                 werden sollen: 0: MsgFenster, 1: Editoren, 2: 
  261.                 Stichwortlisten
  262.  9      art     Cat->ACC, offene Fenster, mess[5+6] enth„lt den Pointer 
  263.                 auf den Buffer, der vorher bergeben wurde. In dem Buffer
  264.                 steht die Liste der Fensterhandles, wenn das vom AES aus 
  265.                 klappt. mess[7] enth„lt die Anzahl der Fenster, die von 
  266.                 CAT geliefert werden.
  267.  
  268. Die folgenden Msgs werden aber zun„chst einmal nur von MsgFenstern 
  269. untersttzt.
  270.  
  271. CatWinInfo
  272. 10      whdl    ACC->Cat, Informationen anfordern. mess[5+6] enh„lt eine 
  273.                 Adresse, die sagt, wo die Informationen sollen , Format der 
  274.                 Information wie "winInfo" (noch nicht festgelegt). mess[7] 
  275.                 enth„lt die L„nge des Buffers in mess[5+6].
  276. 10      whdl    Cat->ACC, Information wurde geschrieben, Bufferadresse 
  277.                 wieder in mess[5+6].
  278. CatWhatsIn
  279. 11      whdl    CB->Cat, Welche Informationen werden im angegebenen Fenster 
  280.                 dargestellt?
  281. 11      whdl    Cat->CB mess[5] Gruppe, mess[6] interne MsgNummer
  282. CatPosition
  283. 12      whdl    CB->Cat, Informationen ber MsgPositionen. mess[7] gibt an, 
  284.                 um welche Art es sich handelt: 0 Neue, 1 letzte Position, 2 
  285.                 ab Datum, 3 ab Nummer. In den letzten beiden F„llen wird in 
  286.                 mess[5+6] noch eine Adresse auf einen String bergeben, der 
  287.                 das Datum bzw. die ID enth„lt. Er ist nullterminiert.
  288. 12      whdl    Cat->CB, mess[5] interne Msgenummer; 0xffff heižt: Nicht 
  289.                 gefunden
  290. CatNewMess
  291. 13      whdl    CB->Cat, neuen Inhalt setzen: mess[5] Gruppe mess[6] interne 
  292.                 MsgNummer
  293. 13      whdl    Cat->CB mess[5] = 0 -> hat geklappt, mess[5] # 0 -> geht 
  294.                 nich..
  295.  
  296. Hier nun meine erste Idee zu der Sache mit den Fensterwechseln. Dabei gibt 
  297. es jetzt ja ein paar Probleme. Ich muž dann ja den Speicher des Accs 
  298. beschreiben, das sollte ich aber nur nach Aufforderung machen. Wenn der User 
  299. jetzt sehr schnell durch die Msgs durchrennt, dann bekommt das Acc nicht 
  300. jeden Wechsel mit, da es ja immer die neue Informationen anfordern muž. Aber 
  301. den Prozežwechsel kann man dann ja vielleicht doch irgendwie forcieren. Dann 
  302. weiž das Acc zwar, daž es hier einen neuen Inhalt gibt und bekommt auch mit, 
  303. wenn der User weitergebl„ttert hat, ohne daž die Information ber die neue 
  304. Fensterposition schon angekommen ist, es kommt aber nicht zu Verstopfungen. 
  305. Aber vielleicht ist dieses Verhalten ja auch erwnscht, denn wenn er dann 
  306. anh„lt, wird die neue Position ja dargestellt. 
  307.  
  308. CatInform
  309. 14              CB->Cat, Acc in die Fensterwechsel/-”ffnen-Informationsliste 
  310.                 ein-/austragen. mess[5] = 0 austragen, mess[5] = 1 eintragen,
  311.                 mess[6] ist das Window-Handle des ACC-Fensters
  312. 14              Cat->CB Acc ein-/ausgetragen, mess[5] wie oben.
  313. CatWinDirty
  314. 15      whdl    Cat->CB dieses Fenster hat einen neuen Inhalt bzw. wurde 
  315.                 ge”ffnet. mess[5] = 0: neuer Inhalt; 1: getopped; 2: neu 
  316.                 ge”ffnet; 3: geschlossen
  317.  
  318.  
  319. ---- ab hier Erweitungsplanung fr sp„ter, erstmal ist hier Ende der Erweiterung -----
  320. Es wird etwas problematisch, wenn das Acc in die MsgBase schreiben will. 
  321. Zun„chst ist das in Cat nur dann ohne gr”žere Probleme m”glich, wenn auch 
  322. die entsprechende Gruppe ge”ffnet ist. Daher brauche ich das whdl, um damit 
  323. das Gruppenhandle zu bekommen. Mir f„llt auch gerade auf, daž wir noch keine 
  324. M”glichkeit vorgesehen haben, an MsgInfos von Msgs zu kommen, die nicht 
  325. gerade in einem Fenster dargestellt werden. Das muž ja wohl auch noch rein, 
  326. wenn Du damit B„ume markieren willst. Also
  327. 16      whdl    CB->Cat; Infos zu einer anderen Msg aus dieser Gruppe 
  328.                 anfordern. mess[5+6] Pointer wie in Msg Nummer 10, mess[6] 
  329.                 interne Nummer. Leider k”nnen wir dann nicht unterscheiden, 
  330.                 welche Infos angefordert werden sollen. Hmm..
  331. Die Gruppe wird hier also ber das whdl festgelegt, was natrlich nicht so 
  332. sch”n ist. Wie gesagt, wahrscheinlich mssen wir uns beim Schreiben noch 
  333. etwas neues ausdenken. 
  334. Anwort ist dann eine Msg vom Typ 10
  335. 17      whdl    CB->Cat; Flags setzen. mess[5] interne Nummer; mess[6] neue 
  336.                 gesetzte Flags; mess[7] neu gel”schte Flags.
  337. 17      whdl    Cat->CB; Flags setzen; mess[5] = 0 alles ok; mess[5] # 0 = 
  338.                 etwas ist schiefgelaufen.
  339.  
  340. -----------------------------------------------------------------------------*)
  341.  
  342. VAR     watch  : INTEGER;   (* Ist ein WatchDog installiert? *)
  343.         isWatch : BOOLEAN;  (* Soll der auch gefragt werden? *)
  344.  
  345. (* Um sich alle installierten Accs beim XAcc-Protokoll zu merken wird hier ein *) 
  346. (* kleines Array angelegt. Das ist natrlich statisch, aber darber wrde ich  *)
  347. (* mir erstmal noch keine Sorgen machen.. :-)                                  *)
  348. CONST maxAcc = 80;      (* Wegen MTOS von 6 auf 80 erweitert. Zwar kann 
  349.                          * man unter MTOS auch mehr als 80 ACCs und Applikationen 
  350.                          * haben, aber das w„re ziemlich krank *)
  351.  
  352. CONST maxBufLen = 128;  (* L„nge des statischen Textbuffers *)
  353.  
  354.       memDescrSize  = 2048; (* 2 kB globaler Speicher *)
  355.  
  356. TYPE        (* for systems with memory protection (MultiTOS) *)
  357.         memDescr        = RECORD
  358.                             CASE : BOOLEAN OF
  359.                             TRUE:
  360.                               apName  : ARRAY [0..49] OF CHAR; (* our extended application name *)
  361.                               textBuf : ARRAY [0..maxBufLen-1] OF CHAR;
  362.                               dataPtr : data.PtrRecord;
  363.                               mPath   : String255;
  364.                               mName   : String255; |
  365.                             FALSE:
  366.                               allInOne: ARRAY [0..memDescrSize-1] OF CHAR;
  367.                             END;
  368.                           END;
  369.  
  370. VAR accCount : CARDINAL;
  371.     acc      : ARRAY[1..maxAcc] OF INTEGER;
  372.     protoCnt : CARDINAL;
  373.     protoAcc : ARRAY[1..maxAcc] OF INTEGER; (* Noch ein Array fr Apps,
  374.                                              * diesmal fr die, die am CAT-Proto 
  375.                                              * teilnehmen 
  376.                                              *)
  377.     messBuff : ARRAY [0..31] OF INTEGER;    (* Platz fr Messagebuffer *)
  378.     startApId: INTEGER;     (* Von wem kam die letzte AV_STARTPROG *)
  379.     memPtr   : POINTER TO memDescr;         (* global buffer *)
  380.  
  381.  
  382. PROCEDURE SendTextReady();
  383. (* Das wrde n”tig werden, wenn wir XAcc Stufe 1 k”nnen *)
  384. BEGIN
  385. END SendTextReady;
  386.  
  387. PROCEDURE send(msg : CARDINAL; dest : INTEGER; REF data : ARRAY OF WORD);
  388. (* Anpassen, damit man damit demn„chst l„ngere Msgs verschicken kann *)
  389. VAR mess : POINTER TO RECORD
  390.              msg : CARDINAL;
  391.              id  : INTEGER;
  392.              overLength : INTEGER;
  393.              w : ARRAY[0..4] OF WORD
  394.            END;
  395.    z : CARDINAL;
  396. BEGIN
  397.   mess := ADR(messBuff);
  398.   FOR z := 0 TO 4 DO mess^.w[z] := data[z] END;
  399.   mess^.msg := msg;
  400.   mess^.id  := mtAppl.ApplIdent;
  401.   mess^.overLength := 0;
  402.   MagicAES.ApplWrite(dest, 16, mess^);
  403.   MagicAES.WindUpdate(MagicAES.ENDUPDATE); (* Um es auch mal abzuschicken.. *)
  404.   MagicAES.WindUpdate(MagicAES.BEGUPDATE);
  405. END send;
  406.  
  407. PROCEDURE SendMess(msg : CARDINAL; catType : INTEGER; l : LONGCARD; i2, i3, dest : INTEGER);
  408. VAR data : RECORD catType : INTEGER; l : LONGCARD; i2, i3 : INTEGER END;
  409. BEGIN
  410.   data.catType := catType; data.l := l; data.i2 := i2; data.i3 := i3;
  411.   send(msg, dest, data);
  412. END SendMess;
  413.  
  414. PROCEDURE SendMessInt(msg : CARDINAL; catType, i1, i2, i3, i4, dest : INTEGER);
  415. VAR data : RECORD catType, i1, i2, i3, i4 : INTEGER END;
  416. BEGIN
  417.   data.catType := catType; data.i1 := i1; data.i2 := i2; data.i3 := i3; data.i4 := i4;
  418.   send(msg, dest, data);
  419. END SendMessInt;
  420.  
  421. PROCEDURE SendAdr(msg : CARDINAL; catType, i1 : INTEGER; l : LONGCARD; i2, dest : INTEGER);
  422. VAR data : RECORD catType : INTEGER; i1 : INTEGER; l : LONGCARD; i2 : INTEGER END;
  423. BEGIN
  424.   data.catType := catType; data.i1 := i1; data.l := l; data.i2 := i2;
  425.   send(msg, dest, data);
  426. END SendAdr;
  427.  
  428. PROCEDURE SendNewMsgInWdw ();
  429. TYPE mType = RECORD
  430.               messId  : CARDINAL;
  431.               apId    : INTEGER;
  432.               over    : CARDINAL;
  433.               catType : CARDINAL;
  434.               length  : LONGCARD;
  435.               buf     : ADDRESS;
  436.             END;
  437.  VAR mPtr: POINTER TO mType;
  438.      i   : CARDINAL;
  439. BEGIN
  440.   mPtr := ADR (messBuff);
  441.   WITH mPtr^ DO
  442.     messId  := CatProtoMsg;
  443.     apId    := mtAppl.ApplIdent;
  444.     over    := 0;
  445.     catType := CAT_NEW_MSG;
  446.     length  := 0;
  447.     buf     := NIL;
  448.   END;
  449.   MagicAES.WindUpdate(MagicAES.ENDUPDATE); (* Um es auch mal abzuschicken.. *)
  450.   FOR i := 1 TO protoCnt - 1 DO 
  451.     MagicAES.ApplWrite (protoAcc[i], 16, mPtr^);
  452.   END;
  453.   MagicAES.WindUpdate(MagicAES.BEGUPDATE);
  454. END SendNewMsgInWdw;
  455.  
  456. PROCEDURE HandleCatProtoMsg (mess: ADDRESS);
  457.  
  458. TYPE mType = RECORD
  459.               messId  : CARDINAL;
  460.               apId    : INTEGER;
  461.               over    : CARDINAL;
  462.               catType : CARDINAL;
  463.               length  : LONGCARD;
  464.               buf     : ADDRESS;
  465.             END;
  466.  
  467.  VAR mPtr: POINTER TO mType;
  468.      wdw : INTEGER;
  469.  
  470.   PROCEDURE ReplyError (mess: ADDRESS);
  471.     VAR to: INTEGER;
  472.   BEGIN
  473.     to := mPtr^.apId;
  474.     mPtr^.apId := mtAppl.ApplIdent;
  475.     mPtr^.length := VAL (LONGCARD, mPtr^.catType) * 65536L;
  476.     mPtr^.catType := CAT_ERROR;
  477.     mPtr^.buf := NIL;
  478.     MagicAES.ApplWrite(to, 16, mPtr^);
  479.     MagicAES.WindUpdate(MagicAES.ENDUPDATE); (* Um es auch mal abzuschicken.. *)
  480.     MagicAES.WindUpdate(MagicAES.BEGUPDATE);
  481.   END ReplyError;
  482.   
  483.   PROCEDURE ReplyOk (mess: ADDRESS);
  484.     VAR to: INTEGER;
  485.   BEGIN
  486.     to := mPtr^.apId;
  487.     mPtr^.apId := mtAppl.ApplIdent;
  488.     mPtr^.catType := CAT_ACK;
  489.     mPtr^.length := 0;
  490.     mPtr^.buf := NIL;
  491.     MagicAES.ApplWrite(to, 16, mPtr^);
  492.     MagicAES.WindUpdate(MagicAES.ENDUPDATE); (* Um es auch mal abzuschicken.. *)
  493.     MagicAES.WindUpdate(MagicAES.BEGUPDATE);
  494.   END ReplyOk;
  495.   
  496.   PROCEDURE Reply (mess: ADDRESS);
  497.     VAR to: INTEGER;
  498.   BEGIN
  499.     to := mPtr^.apId;
  500.     mPtr^.apId := mtAppl.ApplIdent;
  501.     MagicAES.ApplWrite(to, 16, mPtr^);
  502.     MagicAES.WindUpdate(MagicAES.ENDUPDATE); (* Um es auch mal abzuschicken.. *)
  503.     MagicAES.WindUpdate(MagicAES.BEGUPDATE);
  504.   END Reply;
  505.  
  506.   PROCEDURE RemoveAcc (apId : INTEGER);
  507.     VAR i : CARDINAL;
  508.   BEGIN
  509.     i := 1;
  510.     WHILE (i < protoCnt) & (protoAcc[i] # apId) DO INC (i) END;
  511.     IF i < protoCnt THEN
  512.       FOR i := i TO protoCnt - 2 DO
  513.         protoAcc[i] := protoAcc[i+1];
  514.       END;
  515.       DEC (protoCnt);
  516.     END;
  517.   END RemoveAcc;
  518.  
  519.   PROCEDURE checkId (id : INTEGER): BOOLEAN;
  520.   (* Prft, ob schon ein Prozess mit der ID registriert ist *)
  521.     VAR i : CARDINAL;
  522.   BEGIN
  523.     FOR i := 1 TO protoCnt - 1 DO 
  524.       IF protoAcc[i] = id THEN RETURN FALSE END;
  525.     END;
  526.     RETURN id # mtAppl.ApplIdent;
  527.   END checkId;
  528.   
  529.   PROCEDURE AddAcc (apId: INTEGER) : BOOLEAN;
  530.   BEGIN
  531.     IF (protoCnt < maxAcc) & checkId (apId)
  532.     THEN
  533.       protoAcc[protoCnt] := apId; (* ID des Acc, das sich gerade anmeldet *)
  534.       INC(protoCnt);
  535.       RETURN TRUE;
  536.     ELSE
  537.       RETURN FALSE;
  538.     END;
  539.   END AddAcc;
  540.  
  541. TYPE    dateRecType = RECORD
  542.                         date: CARDINAL;
  543.                         time: CARDINAL;
  544.                       END;
  545.  
  546.   VAR   dateRecPtr : POINTER TO dateRecType;
  547.         strPtr     : POINTER TO ARRAY [0..32767] OF CHAR;
  548.         lcPtr      : POINTER TO LONGCARD;
  549.         intPtr     : POINTER TO INTEGER;
  550.         lCard      : LONGCARD;
  551.         sizeReq    : BOOLEAN;
  552.         dist       : data.tDistribution;
  553.         date       : ConvertDate.Date;
  554.         time       : ConvertDate.Time;
  555.  
  556. BEGIN
  557.   mPtr := mess;
  558.   IF (mPtr^.catType > CAT_WDW_NAME) & (mPtr^.catType # CAT_NEW_MSG) & (mPtr^.catType # CAT_TERMINATE)
  559.   THEN
  560.     ReplyError (mess);
  561.     RETURN;
  562.   END;
  563.   CASE mPtr^.catType OF
  564.       CAT_ACK        : ;
  565.     | CAT_ERROR      : ;
  566.     | CAT_LOGIN      : 
  567.         (* ACC anmelden *)
  568.         IF AddAcc (mPtr^.apId)
  569.         THEN
  570.           ReplyOk (mess);
  571.         ELSE
  572.           ReplyError (mess);
  573.         END;
  574.     | CAT_LOGOFF     : 
  575.         RemoveAcc(mPtr^.apId);
  576.         ReplyOk (mess);
  577.     | CAT_NEW_MSG    :
  578.     | CAT_TERMINATE  :
  579.   ELSE
  580.     (* Window von grin erfragen *)
  581.     grin.GetGrinTopWdw (wdw);
  582.     IF wdw < 0
  583.     THEN
  584.       ReplyError (mess);
  585.       RETURN;
  586.     END;
  587.     (* Andere Nachricht *)
  588.     IF mPtr^.length = 0
  589.     THEN
  590.       lcPtr := ADR (mPtr^.length);
  591.       sizeReq := TRUE;
  592.     ELSE
  593.       lcPtr := ADR (lCard);
  594.       sizeReq := FALSE;
  595.     END;
  596.     (* Gr”ženabfrage *)
  597.     CASE mPtr^.catType OF
  598.         CAT_SENDER     : 
  599.           lcPtr^ := grin.ActFromSize (wdw);
  600.       | CAT_RNAME      : 
  601.           lcPtr^ := grin.ActNameSize (wdw);
  602.       | CAT_RECEIVER   : 
  603.           lcPtr^ := grin.ActReceiverSize (wdw);
  604.       | CAT_MAUS_ID    : 
  605.           lcPtr^ := grin.ActIdSize (wdw);
  606.       | CAT_MSG_ID     : 
  607.           lcPtr^ := grin.ActMIdSize (wdw);
  608.       | CAT_MAUS_REF   : 
  609.           lcPtr^ := grin.ActRefIdSize (wdw);
  610.       | CAT_REF        : 
  611.           lcPtr^ := grin.ActRIdSize (wdw);
  612.       | CAT_TOPIC      : 
  613.           lcPtr^ := grin.ActSubjectSize (wdw);
  614.       | CAT_BOX        : 
  615.           lcPtr^ := grin.ActBoxSize (wdw);
  616.       | CAT_GATE       : 
  617.           lcPtr^ := grin.ActGateSize (wdw);
  618.       | CAT_DIST       : 
  619.           lcPtr^ := grin.ActDistSize (wdw);
  620.       | CAT_MIME       : 
  621.           lcPtr^ := grin.ActMimeSize (wdw);
  622.       | CAT_STATUS     : 
  623.           lcPtr^ := grin.ActStatusSize (wdw);
  624.       | CAT_FOLLOWUP   : 
  625.           lcPtr^ := grin.ActFollowupSize (wdw);
  626.       | CAT_REPLYTO    : 
  627.           lcPtr^ := grin.ActReplyToSize (wdw);
  628.       | CAT_TEXT       : 
  629.           lcPtr^ := grin.ActTextSize (wdw);
  630.       | CAT_MSG_DATE   : 
  631.           lcPtr^ := grin.ActDateSize (wdw);
  632.       | CAT_STATUS_DATE: 
  633.           lcPtr^ := grin.ActStatusDateSize (wdw);
  634.       | CAT_GROUP      : 
  635.           lcPtr^ := grin.ActGroupSize (wdw);
  636.       | CAT_ORG_TEXT   : 
  637.           lcPtr^ := grin.ActOrgTextSize (wdw);
  638.       | CAT_IS_OWN     : 
  639.           lcPtr^ := grin.ActIsOwnSize (wdw);
  640.       | CAT_UNIQUE_ID  : 
  641.           lcPtr^ := grin.ActInternalIdSize (wdw);
  642.       | CAT_REAL_SENDER: 
  643.           lcPtr^ := grin.ActSenderSize (wdw);
  644.       | CAT_WDW_NAME   : 
  645.           lcPtr^ := grin.ActWdwNameSize (wdw);
  646.     ELSE
  647.     END;
  648.     IF sizeReq
  649.     THEN
  650.       (* Antwort schicken *)
  651.       Reply (mess);
  652.     ELSE
  653.       (* Datenabfrage *)
  654.       IF (lCard > mPtr^.length)
  655.       OR (mPtr^.buf = NIL)
  656.       THEN
  657.         ReplyError (mess);
  658.         RETURN ;
  659.       END;
  660.       strPtr := mPtr^.buf;
  661.       dateRecPtr := mPtr^.buf;
  662.       CASE mPtr^.catType OF
  663.           CAT_SENDER     : 
  664.             grin.ActualFrom   (wdw, strPtr^);
  665.         | CAT_RNAME      : 
  666.             grin.ActualName   (wdw, strPtr^);
  667.         | CAT_RECEIVER   : 
  668.             grin.ActualReceiver (wdw, strPtr^);
  669.         | CAT_MAUS_ID    : 
  670.             grin.ActualID       (wdw, strPtr^);
  671.         | CAT_MSG_ID     : 
  672.             grin.ActualMId      (wdw, strPtr^);
  673.         | CAT_MAUS_REF   : 
  674.             grin.ActualRefId    (wdw, strPtr^);
  675.         | CAT_REF        : 
  676.             grin.ActualRId      (wdw, strPtr^);
  677.         | CAT_TOPIC      : 
  678.             grin.ActualSubject  (wdw, strPtr^);
  679.         | CAT_BOX        : 
  680.             grin.ActualBox  (wdw, strPtr^);
  681.         | CAT_GATE       : 
  682.             grin.ActualGate     (wdw, strPtr^);
  683.         | CAT_DIST       : 
  684.             grin.ActualDist     (wdw, dist);
  685.             strPtr^[0] := CHR(ORD (dist) + ORD('K'));
  686.             strPtr^[1] := 0C;
  687.         | CAT_MIME       : 
  688.             grin.ActualMime     (wdw, strPtr^);
  689.         | CAT_STATUS     : 
  690.             grin.ActualStatus   (wdw, strPtr^);
  691.         | CAT_FOLLOWUP   : 
  692.             grin.ActualFollowup (wdw, strPtr^);
  693.         | CAT_REPLYTO    : 
  694.             grin.ActualReplyto  (wdw, strPtr^);
  695.         | CAT_TEXT       : 
  696.             grin.ActualText     (wdw, mPtr^.buf);
  697.         | CAT_MSG_DATE   : 
  698.             grin.ActualDate     (wdw, date, time);
  699.             dateRecPtr^.date := ConvertDate.PackDate (date);
  700.             dateRecPtr^.time := ConvertDate.PackTime (time);
  701.         | CAT_STATUS_DATE: 
  702.             grin.ActualStatusDate (wdw, date, time);
  703.             dateRecPtr^.date := ConvertDate.PackDate (date);
  704.             dateRecPtr^.time := ConvertDate.PackTime (time);
  705.         | CAT_GROUP      : 
  706.             grin.ActualGroup  (wdw, strPtr^);
  707.         | CAT_ORG_TEXT   : 
  708.             grin.ActualOrgText (wdw, mPtr^.buf);
  709.         | CAT_IS_OWN     : 
  710.             grin.ActualIsOwn  (wdw, v.bool);
  711.             intPtr := mPtr^.buf;
  712.             IF v.bool
  713.             THEN
  714.               intPtr^ := 1;
  715.             ELSE
  716.               intPtr^ := 0;
  717.             END; 
  718.         | CAT_UNIQUE_ID  : 
  719.             lcPtr := mPtr^.buf;
  720.             grin.ActualInternalId  (wdw, lcPtr^); 
  721.         | CAT_REAL_SENDER: 
  722.             grin.ActualSender (wdw, strPtr^);
  723.         | CAT_WDW_NAME   : 
  724.             grin.ActualWdwName (wdw, strPtr^);
  725.       ELSE
  726.       END;
  727.       Reply (mess);
  728.     END;
  729.   END;
  730. END HandleCatProtoMsg;
  731.  
  732. PROCEDURE HandleCatMsg(m : ADDRESS);
  733. (* Hier ist die Schaltzentrale fr das CatProtokoll *)
  734. TYPE mType = RECORD
  735.               messId  : CARDINAL;
  736.               apId    : INTEGER;
  737.               over    : INTEGER;
  738.               catType : INTEGER;
  739.               CASE : INTEGER OF 
  740.                0 : data    : ARRAY[0..3] OF INTEGER; |
  741.                1 : d0      : INTEGER;
  742.                    adr     : ADDRESS;
  743.                    d3      : INTEGER; |
  744.               END;
  745.             END;
  746.     grInfoType = RECORD
  747.               gr: CARDINAL;
  748.               nr: CARDINAL;
  749.               am: LONGCARD;
  750.             END;
  751. VAR mess : POINTER TO mType;
  752.     a    : POINTER TO ADDRESS;
  753.     wAnz : INTEGER;
  754.     grInfo: grInfoType;
  755.     b    : POINTER TO grInfoType;
  756. BEGIN
  757.   mess := m;
  758.   CASE mess^.catType OF
  759.     CatGreetings    : SendMessInt(CatMsg, CatGreetings, CatProtoVersion,0,0,0, mess^.apId); 
  760.       (* "Hallo Acc, hier bin ich und das ist meine Versionsnummer!" *)
  761.   | enableWatchDog  : 
  762.                       IF watch < 0 THEN RETURN END;
  763.                       isWatch := TRUE;
  764.                       SendMessInt(CatMsg, CatAffirm,  0,0,0,1,  watch);
  765.   | disableWatchDog : 
  766.                       IF watch < 0 THEN RETURN END;
  767.                       isWatch := FALSE;
  768.                       SendMessInt(CatMsg, CatAffirm,  0,0,0,0,  watch);
  769.   (*$? grin.grinWindowProto:
  770.   | WdwManager      : (* Typ in data[0] *)
  771.                       IF mess^.data[0] = 0 THEN
  772.                         a := ADR(mess^.adr); (* Dort sollen sie hin. *)
  773.                         grin.getAllWinds(a^, mess^.data[3], wAnz); (* Fenster besorgen *)
  774.                         SendAdr(CatMsg, WdwManager, 0, a^, wAnz,  mess^.apId);
  775.                       ELSE
  776.                         (* K”nnen wir noch nicht *)
  777.                         SendAdr(CatMsg, WdwManager, mess^.data[0], a^, 0,  mess^.apId);
  778.                       END;
  779.   | CatWinInfo      : a := ADR(mess^.adr); (* Dort sollen sie hin. *)
  780.                       IF grin.getInfo(mess^.data[0], a^, LONGCARD(LONG((mess^.data[3])))) THEN
  781.                         SendAdr(CatMsg, CatWinInfo, mess^.data[0], mess^.adr, mess^.data[3], mess^.apId);
  782.                       ELSE
  783.                         SendAdr(CatMsg, CatWinInfo, mess^.data[0], 0, 0, mess^.apId);
  784.                       END;
  785.   | CatWhatsIn      : b := mess^.adr;
  786.                       IF grin.getBasicInfo(mess^.data[0], grInfo.gr, grInfo.nr, grInfo.am) THEN
  787.                         b^ := grInfo;
  788.                         SendAdr(CatMsg, CatWinInfo, mess^.data[0], LONGCARD(b), 0, mess^.apId);
  789.  
  790.                         (* SendMessInt(CatMsg, CatWhatsIn, mess^.data[0], INTEGER(gr), INTEGER(nr), INTEGER(am), mess^.apId); *)
  791.                         (* sind eigentlich CARDINAL-Werte, aber die Typkonversion „ndert ja nichts.. *)
  792.                       ELSE
  793.                         SendAdr(CatMsg, CatWinInfo, mess^.data[0], 0, 0, mess^.apId);
  794.                         (* SendMessInt(CatMsg, CatWhatsIn, mess^.data[0], 0, 0,0, mess^.apId); *)
  795.                       END;
  796.   | CatPosition     : a := ADR(mess^.adr);
  797.                       SendMessInt(CatMsg, CatPosition, 
  798.                                   mess^.data[0], 
  799.                                   INTEGER(grin.getPos(a^, mess^.data[3], mess^.data[0])), 
  800.                                   0,0,  mess^.apId);
  801.   | CatNewMess      : IF grin.switchMess(mess^.data[0], CARDINAL(mess^.data[2]), CARDINAL(mess^.data[1])) THEN
  802.                         wAnz := 0;
  803.                       ELSE
  804.                         wAnz := 1;
  805.                       END;
  806.                       SendMessInt(CatMsg, CatNewMess,  wAnz,0,0,0, mess^.apId);
  807.   | CatInform       :
  808.   (* CatWinDirty kommt hier nicht an.. :-) *)
  809.   *)
  810.   ELSE
  811.   END;
  812. END HandleCatMsg;
  813.  
  814.  
  815. (* TYPE watchType = (pCatAccept, pCatForget, pCatFiltered); *)
  816. PROCEDURE AcceptThis(VAR ptr : data.PtrRecord):watchType;
  817. (* Diese Prozedur wird von parser.i benutzt, um herauszufinden, ob die gerade   *)
  818. (* reinkommende Msg passieren darf                                              *)
  819. VAR mess  : POINTER TO RECORD mess : CARDINAL; w : ARRAY[1..7] OF INTEGER; END;
  820.     event : BITSET; dr : RECORD x,y,w,h : INTEGER END;
  821.     retry,
  822.     noMess : CARDINAL;
  823. BEGIN
  824.   mess := ADR(messBuff);
  825.   (* Block umkopieren in globalen Speicher *)
  826.   memPtr^.dataPtr := ptr;
  827.   IF isWatch THEN
  828.     SendMess(HelloWatchDog, CatAsk, LONGCARD(ADR(memPtr^.dataPtr)), 0,0, watch);
  829.     retry := 0;
  830.     noMess:= 0;
  831.     REPEAT (* Eine kleine Schleife mit TimeOut und Retry-Z„hler *)
  832.       event := MagicAES.EvntMulti(
  833.                {MagicAES.MUMESAG, MagicAES.MUTIMER},
  834.                 0,{},{}, 0,dr, 0,dr, mess^, 1000,0,
  835.                 v.int, v.int, v.bset, v.int, v.bset, v.int, v.char, v.int);
  836.  
  837.       IF (MagicAES.MUMESAG IN event) &
  838.          (mess^.mess # HelloWatchDog) OR
  839.          ((mess^.w[3] # CatForget) & (mess^.w[3] # CatAccept) & (mess^.w[3] # CatFiltered)) THEN
  840.  
  841.         (* Standardmessages direkt verarbeiten *)
  842.         IF ~HandleEvent (event, mess^, {}, {}, 0C, 0C, 0, 0, 0, 0)
  843.         THEN
  844.           (* Nicht verarbeitet? Aufbewahren, wird vielleicht sp„ter 
  845.            * mal verarbeitet 
  846.            *)
  847.           MagicAES.ApplWrite(mtAppl.ApplIdent, 16, mess^);
  848.         END;
  849.  
  850.         INC(noMess);
  851.         IF noMess > 100 THEN
  852.           event  := {MagicAES.MUTIMER};
  853.           noMess := 0;
  854.         END;
  855.       END;
  856.  
  857.       IF event = {MagicAES.MUTIMER} THEN (* entweder sowieso oder von oben *)
  858.         INC(retry);
  859.         IF    retry > 5 THEN isWatch := FALSE
  860.         ELSIF retry > 2 THEN
  861.           IF 2 = mtAlerts.Alert(1,'[2][CAT:|WatchDog antwortet nicht!][[Nochmal|[Abschalten]') THEN
  862.             isWatch := FALSE
  863.           END;
  864.         END;
  865.       END;
  866.  
  867.     UNTIL (mess^.mess = HelloWatchDog) &
  868.           ((mess^.w[3] = CatForget) OR (mess^.w[3] = CatAccept) OR (mess^.w[3] = CatFiltered)) OR ~isWatch;
  869.     IF isWatch THEN
  870.       IF    mess^.w[3] = CatAccept THEN
  871.         RETURN pCatAccept
  872.       ELSIF mess^.w[3] = CatForget THEN
  873.         RETURN pCatForget
  874.       ELSIF mess^.w[3] = CatFiltered THEN
  875.         RETURN pCatFiltered
  876.       ELSE
  877.         (* Meckern? *)
  878.         RETURN pCatAccept
  879.       END;
  880.     ELSE
  881.       RETURN pCatAccept
  882.     END;
  883.   ELSE
  884.     RETURN pCatAccept
  885.   END;
  886. END AcceptThis;
  887.  
  888. PROCEDURE SendTerminate(terminate: BOOLEAN);
  889. (* Nachricht an den WatchDog schicken, daž Cat beendet wurde *)
  890. TYPE mType = RECORD
  891.               messId  : CARDINAL;
  892.               apId    : INTEGER;
  893.               over    : CARDINAL;
  894.               catType : CARDINAL;
  895.               length  : LONGCARD;
  896.               buf     : ADDRESS;
  897.             END;
  898.   VAR m : POINTER TO RECORD
  899.             messId : CARDINAL;
  900.             apId   : INTEGER;
  901.             over   : INTEGER;
  902.             r      : ARRAY[3..7] OF INTEGER;
  903.           END;
  904.   VAR mPtr: POINTER TO mType;
  905.       i : CARDINAL;
  906. BEGIN
  907.   IF watch >= 0 THEN
  908.     SendMess(HelloWatchDog, CatTerminate, 0,0,0, watch);
  909.   END;
  910.   (* Und unter MultiTOS auch noch ACC_EXIT verschicken an alle 
  911.    * anderen Applikationen, die sich gemeldet haben
  912.    *)
  913.   IF terminate & multiTask
  914.   THEN
  915.     m := ADR(messBuff);
  916.     WITH m^ DO
  917.       messId := ACC_EXIT;
  918.       apId   := mtAppl.ApplIdent;
  919.       over   := 0;
  920.     END;
  921.     MagicAES.WindUpdate(MagicAES.ENDUPDATE);
  922.     FOR i := 1 TO accCount - 1 DO
  923.       MagicAES.ApplWrite(acc[i], 16, m^);
  924.     END;
  925.     MagicAES.WindUpdate(MagicAES.BEGUPDATE);
  926.   ELSE
  927.     accCount := 1;
  928.   END;
  929.  
  930.   IF terminate
  931.   THEN
  932.     mPtr := ADR (messBuff);
  933.     WITH mPtr^ DO
  934.       messId  := CatProtoMsg;
  935.       apId    := mtAppl.ApplIdent;
  936.       over    := 0;
  937.       catType := CAT_TERMINATE;
  938.       length  := 0;
  939.       buf     := NIL;
  940.     END;
  941.     MagicAES.WindUpdate(MagicAES.ENDUPDATE); (* Um es auch mal abzuschicken.. *)
  942.     FOR i := 1 TO protoCnt - 1 DO 
  943.       MagicAES.ApplWrite (protoAcc[i], 16, mPtr^);
  944.     END;
  945.     MagicAES.WindUpdate(MagicAES.BEGUPDATE);
  946.   END;
  947. END SendTerminate;
  948.  
  949. PROCEDURE SendProgstart(error : BOOLEAN);
  950. (* dem Acc mitteilen, ob der Programmstart geklappt hat, not yet implementet *)
  951.   VAR val : INTEGER;
  952. BEGIN
  953.   IF error THEN val := 0 ELSE val := 1 END;
  954.   SendMess(VA_PROGSTART, val, 0,0,0, startApId);
  955. END SendProgstart;
  956.  
  957. PROCEDURE SendAcknowledge (apId : INTEGER; succ: BOOLEAN);
  958.   VAR val : INTEGER;
  959. BEGIN
  960.   IF succ THEN val := 1 ELSE val := 0 END;
  961.   SendMess (ACC_ACK, val, 0,0,0, apId);
  962. END SendAcknowledge;
  963.  
  964. PROCEDURE SendVaWindopen (apId : INTEGER; error : BOOLEAN);
  965. (* Das ist unbenutzt, ist wohl auch nur in Gemini sinnvoll *)
  966. BEGIN
  967.   IF error 
  968.   THEN
  969.     SendMess(VA_WINDOPEN, 0, 0,0,0, apId);
  970.   ELSE
  971.     SendMess(VA_WINDOPEN, 1, 0,0,0, apId);
  972.   END;
  973. END SendVaWindopen;
  974.  
  975. PROCEDURE FindAVServer (VAR id: INTEGER): BOOLEAN;
  976.   CONST cAVServer = "AVSERVER=";
  977.   VAR avServer : ARRAY [0..79] OF CHAR;
  978.       i        : INTEGER;
  979.       apType   : INTEGER;
  980. BEGIN
  981.   FOR i := 0 TO 79 DO avServer[i] := 0C; END;
  982.   id := -1;
  983.   IF mtCommand.EnvVar (cAVServer, avServer)
  984.   THEN
  985.     FOR i := 0 TO 7 DO 
  986.       IF avServer[i] = 0C
  987.       THEN
  988.         avServer[i] := ' ';
  989.       END;
  990.     END;
  991.     avServer[8] := 0C;
  992.     id := MagicAES.ApplFind (ADR(avServer));
  993.   END;
  994.   IF id < 0
  995.   THEN
  996.     (* Nach Applikation AVSERVER suchen *)
  997.     MagicStrings.Assign (cAVServer, avServer);
  998.     avServer[8] := 0C;
  999.     id := MagicAES.ApplFind (ADR(avServer));
  1000.   END;
  1001.   IF id < 0
  1002.   THEN
  1003.     (* Shell mit appl_search suchen *)
  1004.     IF multiTOS OR (magIx & (magIxVer >= $200))
  1005.     THEN
  1006.       IF MagicAES.ApplSearch (MagicAES.APSHELL, avServer, apType, id)
  1007.       THEN
  1008.         IF apType # MagicAES.APTAPP
  1009.         THEN
  1010.           id := -1;
  1011.         END;
  1012.       END;
  1013.     END;
  1014.   END;
  1015.   RETURN id >= 0;
  1016. END FindAVServer;
  1017.  
  1018. PROCEDURE SendPathUpdate (REF path: ARRAY OF CHAR);
  1019. (* Schickt ein AV_PATH_UPDATE an den AV_SERVER *)
  1020.   VAR mess : POINTER TO RECORD
  1021.                messId : INTEGER;
  1022.                apId   : INTEGER;
  1023.                over   : INTEGER;
  1024.                fPath              : ADDRESS;
  1025.                fName              : ADDRESS;
  1026.                e15                : INTEGER;
  1027.              END;
  1028.      avId : INTEGER;
  1029. BEGIN
  1030.   IF ~FindAVServer (avId)
  1031.   THEN
  1032.     (* Wir schicken das an ID 0 *)
  1033.     avId := 0;
  1034.   END;
  1035.   (* Wir schicken nichts an uns selbst *)
  1036.   IF (avId = mtAppl.ApplIdent) THEN RETURN END;
  1037.   mess := ADR (messBuff);
  1038.   MagicStrings.Assign (FileNames.FilePath(path), memPtr^.mPath);
  1039.   WITH mess^ DO
  1040.     messId := AV_PATH_UPDATE;
  1041.     apId   := mtAppl.ApplIdent;
  1042.     over   := 0;
  1043.     fPath  := ADR (memPtr^.mPath);
  1044.     fName  := NIL;
  1045.     e15    := 0;
  1046.   END;
  1047.   MagicAES.ApplWrite(avId, 16, mess^);
  1048. END SendPathUpdate;
  1049.  
  1050. PROCEDURE SendOpenwind (id : INTEGER; path, name : ADDRESS);
  1051. (* einer anderen Applikation sagen, das sie ein Fenster ”ffnen soll
  1052.  * ist fr den Fall, das CAT oder Eddix schon ge”ffnet sind, dann wird 
  1053.  * diese Message verschickt.
  1054.  *)
  1055.   VAR mess : POINTER TO RECORD
  1056.                messId : INTEGER;
  1057.                apId   : INTEGER;
  1058.                over   : INTEGER;
  1059.                fPath              : ADDRESS;
  1060.                fName              : ADDRESS;
  1061.                e15                : INTEGER;
  1062.              END;
  1063.      fPtr  : Str255Ptr;
  1064. BEGIN
  1065.   mess := ADR (messBuff);
  1066.   (* Filenamen und Pfad kopieren *)
  1067.   fPtr := path;
  1068.   MagicStrings.Assign (fPtr^, memPtr^.mPath);
  1069.   fPtr := name;
  1070.   MagicStrings.Assign (fPtr^, memPtr^.mName);
  1071.   WITH mess^ DO
  1072.     messId := AV_OPENWIND;
  1073.     apId   := mtAppl.ApplIdent;
  1074.     over   := 0;
  1075.     fPath  := ADR (memPtr^.mPath);
  1076.     fName  := ADR (memPtr^.mName);
  1077.     e15    := 0;
  1078.   END;
  1079.   MagicAES.ApplWrite(id, 16, mess^);
  1080.   MagicAES.WindUpdate(MagicAES.ENDUPDATE); (* Um es auch mal abzuschicken.. *)
  1081.   MagicAES.WindUpdate(MagicAES.BEGUPDATE);
  1082. END SendOpenwind;
  1083.  
  1084. PROCEDURE SendHelp (VAR str : ARRAY OF CHAR);
  1085.   (* Request Help via PC_HELP Protokoll *)
  1086.   VAR accId : INTEGER;
  1087.       mess  : POINTER TO RECORD
  1088.                messId : INTEGER;
  1089.                apId   : INTEGER;
  1090.                over   : INTEGER;
  1091.                data   : ADDRESS;
  1092.                fName  : ADDRESS;
  1093.                e15    : INTEGER;
  1094.              END;
  1095.      helpApp: ARRAY [0..9] OF CHAR; 
  1096.      i      : INTEGER;
  1097. BEGIN
  1098.   mess := ADR(messBuff);
  1099.   (* String kopieren in statischen Buffer (igitt) *)
  1100.   i := 0;
  1101.   WHILE (i < maxBufLen-1) & (str[i] # 0C) DO
  1102.     memPtr^.textBuf[i] := str[i];
  1103.     INC (i);
  1104.   END;
  1105.   memPtr^.textBuf [i] := 0C;
  1106.   (* Search for PC/TC-HELP Accessory *)
  1107.   MagicStrings.Assign (UserBLK.helpServer, helpApp);
  1108.   accId := MagicStrings.Length (helpApp);
  1109.   (* Extend name with Spaces *)
  1110.   WHILE accId < 8 DO 
  1111.     helpApp[accId] := ' '; 
  1112.     helpApp[accId+1] := ''; 
  1113.     INC (accId);
  1114.   END;
  1115.   accId := MagicAES.ApplFind (ADR(helpApp));
  1116.   IF accId >= 0
  1117.   THEN
  1118.     WITH mess^ DO
  1119.       messId := AC_HELP;
  1120.       apId   := mtAppl.ApplIdent;
  1121.       over   := 0;
  1122.       data   := ADR(memPtr^.textBuf);
  1123.     END;
  1124.     MagicAES.ApplWrite (accId, 16, mess^);
  1125.   END;
  1126. END SendHelp;
  1127.  
  1128. PROCEDURE Send2Filter (to: INTEGER; length: CARDINAL; what: ADDRESS): BOOLEAN;
  1129.   (* Request Help via PC_HELP Protokoll *)
  1130.   VAR mess  : POINTER TO RECORD
  1131.                messId : CARDINAL;
  1132.                apId   : INTEGER;
  1133.                over   : INTEGER;
  1134.                len    : CARDINAL;
  1135.                data   : ADDRESS;
  1136.                res1,
  1137.                res2   : INTEGER;
  1138.              END;
  1139.      helpApp: ARRAY [0..9] OF CHAR; 
  1140.      i      : INTEGER;
  1141. BEGIN
  1142.   mess := ADR(messBuff);
  1143.   (* Daten kopieren in globalen Buffer *)
  1144.   IF length > memDescrSize THEN RETURN FALSE END;
  1145.   Block.Copy (what, length, memPtr);
  1146.   WITH mess^ DO
  1147.     messId := Cat2FiltMsg;
  1148.     apId   := mtAppl.ApplIdent;
  1149.     over   := 0;
  1150.     len    := length;
  1151.     data   := ADR(memPtr^.allInOne);
  1152.     res1   := 0;
  1153.     res2   := 0;
  1154.   END;
  1155.   MagicAES.ApplWrite (to, 16, mess^);
  1156.   MagicAES.WindUpdate(MagicAES.ENDUPDATE); (* Um es auch mal abzuschicken.. *)
  1157.   MagicAES.WindUpdate(MagicAES.BEGUPDATE);
  1158.   RETURN TRUE;
  1159. END Send2Filter;
  1160.  
  1161. PROCEDURE SendExtendedHelp (VAR str : ARRAY OF CHAR; VAR text: ARRAY OF CHAR): BOOLEAN;
  1162.   (* Request Help via VA_START from ST-GUIDE *)
  1163.   CONST theGuide    = 'ST-GUIDE';
  1164.   
  1165.   VAR accId : INTEGER;
  1166.       vaMess: POINTER TO RECORD
  1167.                messId : INTEGER;
  1168.                apId   : INTEGER;
  1169.                over   : INTEGER;
  1170.                cmd    : ADDRESS;
  1171.                res    : LONGINT;
  1172.                res2   : INTEGER;
  1173.              END;
  1174.       helpApp: ARRAY [0..9] OF CHAR; 
  1175. BEGIN
  1176.   (* Search for ST-Guide Accessory/Applikation *)
  1177.   MagicStrings.Assign (theGuide, helpApp);
  1178.   accId := MagicAES.ApplFind (ADR(helpApp));
  1179.   IF accId < 0
  1180.   THEN
  1181.     (* ST-Guide nicht gefunden, interne Hilfe aufrufen *)
  1182.     RETURN FALSE
  1183.   END;
  1184.   
  1185.   (* Kommandozeile fr VA_START aufbauen *)
  1186.   (* hier kann ich das per Assign machen, da die internen
  1187.    * Hilfeberschriften nie den statischen Buffer berschreiten 
  1188.    * werden 
  1189.    *)
  1190.   MagicStrings.Assign ("*:\", memPtr^.allInOne);
  1191.   MagicStrings.Append (text, memPtr^.allInOne);
  1192.   MagicStrings.Append (" ", memPtr^.allInOne);
  1193.   MagicStrings.Append (str, memPtr^.allInOne);
  1194.   
  1195.   vaMess := ADR(messBuff);
  1196.   WITH vaMess^ DO
  1197.     messId := VA_START;
  1198.     apId   := mtAppl.ApplIdent;
  1199.     over   := 0;
  1200.     cmd    := ADR(memPtr^.allInOne);
  1201.     res    := 0;
  1202.     res2   := 0;
  1203.   END;
  1204.   MagicAES.ApplWrite (accId, 16, vaMess^);
  1205.  
  1206.   MagicAES.WindUpdate(MagicAES.ENDUPDATE); (* Um es auch mal abzuschicken.. *)
  1207.   MagicAES.WindUpdate(MagicAES.BEGUPDATE);
  1208.  
  1209.   RETURN TRUE;
  1210. END SendExtendedHelp;
  1211.  
  1212. PROCEDURE SendPrintFile (REF path, name: ARRAY OF CHAR; withEffects: BOOLEAN): BOOLEAN;
  1213. (* Druckt die angegebene Datei ber Idealist bzw. das CALCLOCK-Protokoll
  1214.  *)
  1215.   CONST ideaList    = 'IDEALIST';
  1216.         ideaAcc     = 'ILIST   ';
  1217.   
  1218.   VAR accId : INTEGER;
  1219.       vaMess: POINTER TO RECORD
  1220.                messId : INTEGER;
  1221.                apId   : INTEGER;
  1222.                over   : INTEGER;
  1223.                len    : INTEGER;
  1224.                ptr    : ADDRESS;
  1225.                copies : INTEGER;
  1226.                bits   : BITSET;
  1227.              END;
  1228.       messy : POINTER TO RECORD
  1229.                messId : INTEGER;
  1230.                apId   : INTEGER;
  1231.                over   : INTEGER;
  1232.                wdw    : INTEGER;
  1233.                magic  : ADDRESS;
  1234.                fName  : ADDRESS;
  1235.              END;
  1236.       helpApp: ARRAY [0..9] OF CHAR; 
  1237.       i      : INTEGER;
  1238.       event  : BITSET; 
  1239.       dr : RECORD x,y,w,h : INTEGER END;
  1240.       retry,
  1241.       noMess : CARDINAL;
  1242. BEGIN
  1243.   (* Erstmal nach Idealist suchen *)
  1244.   MagicStrings.Assign (ideaList, helpApp);
  1245.   accId := MagicAES.ApplFind (ADR(helpApp));
  1246.   IF accId < 0
  1247.   THEN
  1248.     (* Idealist nicht gefunden, IList suchen *)
  1249.     MagicStrings.Assign (ideaAcc, helpApp);
  1250.     accId := MagicAES.ApplFind (ADR(helpApp));
  1251.     IF accId < 0
  1252.     THEN
  1253.       (* Idealist nicht gefunden, IList suchen *)
  1254.       RETURN FALSE
  1255.     END;
  1256.   END;
  1257.   
  1258.   (* Idealist gefunden, Calclock-Message aufbauen *)
  1259.   MagicStrings.Assign (path, memPtr^.allInOne);
  1260.   MagicStrings.Append (name, memPtr^.allInOne);
  1261.  
  1262.   vaMess := ADR(messBuff);
  1263.   WITH vaMess^ DO
  1264.     messId := CALCLOCK;
  1265.     apId   := mtAppl.ApplIdent;
  1266.     over   := 0;
  1267.     len    := LENGTH (memPtr^.allInOne);
  1268.     ptr    := ADR(memPtr^.allInOne);
  1269.     copies := 1;
  1270.     bits   := {};
  1271.     INCL (bits, 0); (* Bit 0 setzen, tenmpor„re Datei l”schen *)
  1272.     IF withEffects
  1273.     THEN
  1274.       INCL (bits, 8);
  1275.     ELSE
  1276.       INCL (bits, 9);
  1277.     END;
  1278.   END;
  1279.  
  1280.   MagicAES.ApplWrite (accId, 16, vaMess^);
  1281.  
  1282.   MagicAES.WindUpdate(MagicAES.ENDUPDATE); (* Um es auch mal abzuschicken.. *)
  1283.  
  1284.   (* Wait for Event *)
  1285.  
  1286.   messy := ADR(messBuff);
  1287.   retry := 0;
  1288.   REPEAT (* Eine kleine Schleife mit TimeOut und Retry-Z„hler *)
  1289.     event := MagicAES.EvntMulti(
  1290.              {MagicAES.MUMESAG, MagicAES.MUTIMER},
  1291.               0,{},{}, 0,dr, 0,dr, messy^, 250,0,
  1292.               v.int, v.int, v.bset, v.int, v.bset, v.int, v.char, v.int);
  1293.  
  1294.     IF (MagicAES.MUMESAG IN event) &
  1295.        (messy^.messId # CALCLOCK_OK) 
  1296.     THEN
  1297.       MagicAES.WindUpdate(MagicAES.BEGUPDATE);
  1298.       (* Standardmessages direkt verarbeiten *)
  1299.       IF ~HandleEvent (event, messy^, {}, {}, 0C, 0C, 0, 0, 0, 0)
  1300.       THEN
  1301.         (* Nicht verarbeitet? Aufbewahren, wird vielleicht sp„ter 
  1302.          * mal verarbeitet 
  1303.          *)
  1304.         MagicAES.ApplWrite(mtAppl.ApplIdent, 16, messy^);
  1305.       END;
  1306.       MagicAES.WindUpdate(MagicAES.ENDUPDATE);
  1307.  
  1308.       INC(noMess);
  1309.       IF noMess > 20 THEN
  1310.         event  := {MagicAES.MUTIMER};
  1311.       END;
  1312.     END;
  1313.     
  1314.     IF (MagicAES.MUTIMER IN event)
  1315.     THEN
  1316.       INC (retry);
  1317.     END;
  1318.   UNTIL (messy^.messId = CALCLOCK_OK) OR (retry > 3);
  1319.   MagicAES.WindUpdate(MagicAES.BEGUPDATE);
  1320.  
  1321.   RETURN messy^.messId = CALCLOCK_OK;
  1322. END SendPrintFile;
  1323.  
  1324. PROCEDURE IsProtokoll(mess : ADDRESS;
  1325.                      VAR kReturn : INTEGER; VAR mokState : BITSET;
  1326.                      VAR pName, pCmd : Str255Ptr):React;
  1327.  
  1328.   PROCEDURE SendToWatchDog();
  1329.   (* WatchDog-Initialisierungsmsg von Cat *)
  1330.   VAR m : POINTER TO RECORD
  1331.             messId : CARDINAL;
  1332.             apId   : INTEGER;
  1333.             over   : INTEGER;
  1334.             r      : ARRAY[3..7] OF INTEGER;
  1335.           END;
  1336.   BEGIN
  1337.     m := ADR(messBuff);
  1338.     WITH m^ DO
  1339.       messId := HelloWatchDog;
  1340.       apId   := mtAppl.ApplIdent;
  1341.       over   := 0;
  1342.       r[3]   := CatGreetings;
  1343.       r[4]   := CatProtoVersion;
  1344.       r[5]   := 0; r[6]   := 0; r[7] := 0;
  1345.     END;
  1346.     MagicAES.ApplWrite(watch, 16, m^);
  1347.     MagicAES.WindUpdate(MagicAES.ENDUPDATE); (* Abschicken *)
  1348.     MagicAES.WindUpdate(MagicAES.BEGUPDATE);
  1349.     isWatch  := FALSE;
  1350.   END SendToWatchDog;
  1351.  
  1352.   PROCEDURE CheckName(VAR str : ARRAY OF CHAR; id : INTEGER);
  1353.   (* Ist das ein WatchDog? Ja -> Begržung losschicken *)
  1354.   VAR i : INTEGER;
  1355.   BEGIN
  1356.     IF MagicStrings.Equal(str, watchDog) THEN
  1357.       watch := id;
  1358.       IF UserBLK.watchBox THEN
  1359.         i := mtAlerts.Alert(1, '[1][CAT:|WatchDog found][[Jippie]');
  1360.       END;
  1361.       SendToWatchDog();
  1362.     END;
  1363.   END CheckName;
  1364.  
  1365.   PROCEDURE CheckNameXACC(mess : ADDRESS);
  1366.   VAR access : POINTER TO RECORD
  1367.                  messId : INTEGER;
  1368.                  apId   : INTEGER;
  1369.                  over   : INTEGER;
  1370.                  version, protoStep : CHAR;
  1371.                  name               : Str255Ptr;
  1372.                  menuId             : INTEGER;
  1373.                  accId              : INTEGER;
  1374.                END;
  1375.   BEGIN
  1376.     access := mess;
  1377.     IF (access^.name > ADDRESS($F000))
  1378.     THEN
  1379.       CheckName(access^.name^, access^.apId);
  1380.     END;
  1381.   END CheckNameXACC;
  1382.  
  1383.   PROCEDURE CheckNameVA(mess : ADDRESS);
  1384.   VAR access : POINTER TO RECORD
  1385.                  messId : INTEGER;
  1386.                  apId   : INTEGER;
  1387.                  over   : INTEGER;
  1388.                  b11, b12, b13      : BITSET;
  1389.                  accName            : Str255Ptr;
  1390.                END;
  1391.   BEGIN
  1392.     access := mess;
  1393.     IF (access^.accName > ADDRESS($F000))
  1394.     THEN
  1395.       CheckName(access^.accName^, access^.apId);
  1396.     END;
  1397.   END CheckNameVA;
  1398.  
  1399.   PROCEDURE accInit(mess : ADDRESS);
  1400.   (* XAcc-Protokoll, accInit behandeln *)
  1401.   VAR i : CARDINAL;
  1402.       access : POINTER TO RECORD
  1403.                  messId : INTEGER;
  1404.                  apId   : INTEGER;
  1405.                  over   : INTEGER;
  1406.                  version, protoStep : CHAR;
  1407.                  name               : Str255Ptr;
  1408.                  menuId             : INTEGER;
  1409.                  accId              : INTEGER
  1410.                END;
  1411.  
  1412.     PROCEDURE checkId (id : INTEGER): BOOLEAN;
  1413.     (* Prft, ob schon ein Prozess mit der ID registriert ist *)
  1414.       VAR i : CARDINAL;
  1415.     BEGIN
  1416.       FOR i := 1 TO accCount - 1 DO 
  1417.         IF acc[i] = id THEN RETURN FALSE END;
  1418.       END;
  1419.       RETURN id # mtAppl.ApplIdent;
  1420.     END checkId;
  1421.     
  1422.   BEGIN
  1423.     access := mess;
  1424.     IF multiTask
  1425.     THEN
  1426.       IF (accCount < maxAcc) & checkId (access^.apId)
  1427.       THEN
  1428.         acc[accCount]     := access^.apId; (* ID des Acc, das sich gerade anmeldet *)
  1429.         IF access^.messId # ACC_ACC
  1430.         THEN
  1431.           access^.messId    := ACC_ACC;
  1432.           access^.apId      := mtAppl.ApplIdent;
  1433.           access^.version   := CHR(20H);
  1434.           access^.protoStep := 1C;
  1435.           access^.name      := ADR(memPtr^.apName);
  1436.           access^.menuId    := 0;
  1437.           access^.accId     := 0;
  1438.   
  1439.           MagicAES.ApplWrite(acc[accCount], 16, access^);
  1440.           MagicAES.WindUpdate(MagicAES.ENDUPDATE); (* Abschicken *)
  1441.           MagicAES.WindUpdate(MagicAES.BEGUPDATE);
  1442.         END;
  1443.         INC(accCount);
  1444.       END;
  1445.     ELSE (* not MultiTOS *)
  1446.       IF (accCount < maxAcc) & checkId (access^.apId) THEN
  1447.   
  1448.         acc[accCount]     := access^.apId; (* ID des Acc, das sich gerade anmeldet *)
  1449.         access^.messId    := ACC_ACC;
  1450.         access^.accId     := access^.apId;
  1451.         access^.apId      := mtAppl.ApplIdent;
  1452.         access^.over      := 0;
  1453.         (* Die anderen Daten stimmen zu diesem Zeitpunkt schon.. *)
  1454.   
  1455.         FOR i := 1 TO accCount-1 DO
  1456.           MagicAES.ApplWrite(acc[i], 16, access^);
  1457.           MagicAES.WindUpdate(MagicAES.ENDUPDATE); (* Abschicken *)
  1458.           MagicAES.WindUpdate(MagicAES.BEGUPDATE);
  1459.         END; (* Alle anderen Accs benachrichtigen *)
  1460.                                    
  1461.         access^.messId    := ACC_ID;
  1462.         access^.version   := CHR(20H);
  1463.         access^.protoStep := 1C;
  1464.         access^.name      := ADR(memPtr^.apName);
  1465.         access^.menuId    := 0;
  1466.         access^.accId     := 0;
  1467.   
  1468.         MagicAES.ApplWrite(acc[accCount], 16, access^);
  1469.         INC(accCount);
  1470.   
  1471.         MagicAES.WindUpdate(MagicAES.ENDUPDATE); (* Abschicken *)
  1472.         MagicAES.WindUpdate(MagicAES.BEGUPDATE);
  1473.       END; 
  1474.     END;
  1475.   END accInit;
  1476.  
  1477.   PROCEDURE SendVaProtostatus(mess : ADDRESS);
  1478.   VAR id : INTEGER;
  1479.       access : POINTER TO RECORD
  1480.                  messId : INTEGER;
  1481.                  apId   : INTEGER;
  1482.                  over   : INTEGER;
  1483.                  b21, b22, b23      : BITSET;
  1484.                  prgName            : ADDRESS;
  1485.                END;
  1486.   BEGIN
  1487.     access := mess;
  1488.     id             := access^.apId;
  1489.     access^.messId := VA_PROTOSTATUS;
  1490.     access^.apId   := mtAppl.ApplIdent;
  1491.     access^.over   := 0;
  1492.     access^.b21    := {xAV_SENDKEY, xAV_ACCWINDOPEN, xAV_STARTPROG, xAV_OPENWIND};
  1493.     access^.b22    := {};
  1494.     access^.b23    := {};
  1495.     access^.prgName:= ADR(memPtr^.apName);
  1496.     MagicAES.ApplWrite(id, 16, access^);
  1497.     MagicAES.WindUpdate(MagicAES.ENDUPDATE); (* Abschicken *)
  1498.     MagicAES.WindUpdate(MagicAES.BEGUPDATE);
  1499.   END SendVaProtostatus;
  1500.   
  1501.   PROCEDURE RemoveAcc (apId : INTEGER);
  1502.     VAR i : CARDINAL;
  1503.   BEGIN
  1504.     i := 1;
  1505.     WHILE (i < accCount) & (acc[i] # apId) DO INC (i) END;
  1506.     IF i < accCount THEN
  1507.       FOR i := i TO accCount - 2 DO
  1508.         acc[i] := acc[i+1];
  1509.       END;
  1510.       DEC (accCount);
  1511.     END;
  1512.   END RemoveAcc;
  1513.  
  1514. VAR access : POINTER TO RECORD
  1515.                messId : INTEGER;
  1516.                apId   : INTEGER;
  1517.                over   : INTEGER;
  1518.                CASE :CARDINAL OF
  1519.                (* AV_SENDKEY *)
  1520.                  1 : mokState       : INTEGER;
  1521.                      kReturn        : INTEGER;
  1522.                      e11, e12, e13  : INTEGER|
  1523.                (* AV_STARTPROG *)
  1524.                  2 : pName, pCmd    : ADDRESS;
  1525.                      e14            : INTEGER|
  1526.                (* AV_OPENWIND  *)
  1527.                  3 : fPath          : ADDRESS;
  1528.                      fName          : ADDRESS;
  1529.                      e15            : INTEGER |
  1530.                  4 : i              : ARRAY[0..4] OF INTEGER|
  1531.                  5 : e16            : INTEGER;
  1532.                      text           : ADDRESS; |
  1533.                END;
  1534.              END;
  1535.  
  1536. (* TYPE React        = (rNoproto, rNone, rChar, rText); *)
  1537. BEGIN
  1538.   access := mess;
  1539.   (* Zun„chst einmal die Initialisierungsmsgs fr XAcc und VA *)
  1540.   IF    access^.messId = ACC_ID   THEN             (* hier behandelt, WatchDog suchen *)
  1541.     CheckNameXACC(mess);
  1542.     accInit(mess);      (* Xacc-Protokoll behandeln *)
  1543.     RETURN rNone;
  1544.   (* AccOpen und AccClose werden einfach berh”rt! *)
  1545.   ELSIF (access^.messId = ACC_ACC) & multiTask THEN  (* hier behandelt, WatchDog suchen *)
  1546.     CheckNameXACC(mess);
  1547.     accInit (mess);
  1548.     RETURN rNone;
  1549.   (* AccOpen und AccClose werden einfach berh”rt! *)
  1550.   ELSIF access^.messId = AV_PROTOKOLL THEN         (* hier behandelt, WatchDog suchen *)
  1551.     CheckNameVA(mess);
  1552.     SendVaProtostatus(mess);                  (* .. und dem Acc sagen, was wir k”nnen *)
  1553.     RETURN rNone;
  1554.   
  1555.   ELSIF access^.messId = ACC_EXIT THEN                    (* XACC Acc_Exit *)
  1556.     (* remove Accessorie from acc list *)
  1557.     RemoveAcc (access^.apId);
  1558.     RETURN rNone;
  1559.   ELSIF access^.messId = ACC_KEY THEN                     (* Tastendruck durchreichen *)
  1560.     (* Genau umgedreht zu AV_SENDKEY *)
  1561.     kReturn := access^.mokState;
  1562.     mokState:= BITSET(access^.kReturn);
  1563.     SendAcknowledge (access^.apId, TRUE);
  1564.     RETURN rChar;
  1565.   ELSIF access^.messId = ACC_TEXT THEN
  1566.     (* get text via XACC *)
  1567.     kReturn := access^.apId;    (* apId merken fr Acknowledge *)
  1568.     pName   := access^.text;    (* Pointer auf Text *)
  1569.     RETURN rText;
  1570.     
  1571.   (* AV-Msgs, die direkt hier behandelt werden *)
  1572.   ELSIF access^.messId = AV_SENDKEY   THEN                (* Tastendruck durchreichen *)
  1573.     kReturn := access^.kReturn;
  1574.     mokState:= BITSET(access^.mokState);
  1575.     RETURN rChar;
  1576.   ELSIF access^.messId = AV_ACCWINDOPEN  THEN  (* AccFenster auf -> rein in die Queue *)
  1577.     NewWindowIsTop(access^.i[0], access^.apId);
  1578.     RETURN rNone;
  1579.   ELSIF access^.messId = AV_ACCWINDCLOSED THEN (* AccFenster zu -> raus aus der Queue *)
  1580.     WindowIsClosed(access^.i[0]);
  1581.     RETURN rNone;
  1582.   ELSIF access^.messId = AV_STARTPROG THEN   (* Acc sagt: Folgendes Programm starten! *)
  1583.     pName := access^.pName; pCmd := access^.pCmd;
  1584.     startApId := access^.apId;
  1585.     RETURN rStart;
  1586.   ELSIF access^.messId = AV_OPENWIND THEN                              (* Woasn doas? *)
  1587.     pName := access^.fPath; pCmd := access^.fName;
  1588.     SendVaWindopen(access^.apId, FALSE);
  1589.     RETURN rOpen;
  1590.   ELSIF access^.messId = VA_START THEN
  1591.     (* Unter Mag!X: Neue Dokumente auf CAT gezogen oder so *)
  1592.     pName := NIL; pCmd := access^.fPath;
  1593.     (* Best„tigung gibt es keine *)
  1594.     RETURN rOpen;
  1595.  
  1596.   ELSIF CARDINAL(access^.messId) = CatMsg THEN                           (* CatMsg *)
  1597.     HandleCatMsg(mess);
  1598.     RETURN rNone;
  1599.   ELSIF CARDINAL(access^.messId) = ExtCatMsg THEN                        (* CatMsg *)
  1600.     kReturn := access^.mokState;
  1601.     RETURN rExtCatMsg;
  1602.   ELSIF CARDINAL(access^.messId) = CatProtoMsg THEN                      (* neues CAT-Protokoll *)
  1603.     (* wird komplett hier behandelt: *)
  1604.     HandleCatProtoMsg (mess);
  1605.     RETURN rNone;
  1606.   ELSE (* Kein bekanntes Protokoll *)
  1607.     RETURN rNoproto;
  1608.   END;
  1609.   RETURN rNoproto;
  1610. END IsProtokoll;
  1611.  
  1612. PROCEDURE ProtoInit ();
  1613. (* XACC-Initialisierung unter MTOS *)
  1614.   VAR i : INTEGER;
  1615.       access : POINTER TO RECORD
  1616.                  messId : INTEGER;
  1617.                  apId   : INTEGER;
  1618.                  over   : INTEGER;
  1619.                  version, protoStep : CHAR;
  1620.                  name               : Str255Ptr;
  1621.                  menuId             : INTEGER;
  1622.                  accId              : INTEGER
  1623.                END;
  1624.      apName : String255;
  1625.      apMode,
  1626.      apType,
  1627.      apId   : INTEGER;
  1628. BEGIN
  1629.   IF multiTOS OR (magIx & (magIxVer >= $200))
  1630.   THEN
  1631.     access := ADR(messBuff);
  1632.     apMode := MagicAES.APFIRST;
  1633.     WHILE MagicAES.ApplSearch (apMode, apName, apType, apId) DO
  1634.       apMode := MagicAES.APNEXT;
  1635.       IF (apType # 1) & (apId # mtAppl.ApplIdent)
  1636.       THEN
  1637.         access^.messId    := ACC_ID;
  1638.         access^.apId      := mtAppl.ApplIdent;
  1639.         access^.version   := CHR(20H);
  1640.         access^.protoStep := 1C;
  1641.         access^.name      := ADR(memPtr^.apName);
  1642.         access^.menuId    := 0;
  1643.         access^.accId     := 0;
  1644.     
  1645.         MagicAES.ApplWrite(apId, 16, access^);
  1646.     
  1647.       END;
  1648.     END;
  1649.   ELSIF magIx & (magIxVer < $200)
  1650.   THEN
  1651.     FOR i := 0 TO MagicAES.AESGlobal.apCount - 1 DO
  1652.       apName[0] := '?';
  1653.       apName[1] := 0C;
  1654.       apName[2] := CHR(i);
  1655.       apName[3] := 0C;
  1656.       apId := MagicAES.ApplFind (ADR(apName));
  1657.       IF (apId # 0) & (apId # mtAppl.ApplIdent)
  1658.       THEN 
  1659.         access^.messId    := ACC_ID;
  1660.         access^.apId      := mtAppl.ApplIdent;
  1661.         access^.version   := CHR(20H);
  1662.         access^.protoStep := 1C;
  1663.         access^.name      := ADR(memPtr^.apName);
  1664.         access^.menuId    := 0;
  1665.         access^.accId     := 0;
  1666.       
  1667.         MagicAES.ApplWrite(apId, 16, access^);
  1668.       END;
  1669.     END;
  1670.   END;
  1671. END ProtoInit;
  1672.  
  1673. PROCEDURE isWatchDog(VAR installed, active : BOOLEAN);
  1674. (* Ist der WatchDog angemeldet und aktiv? *)
  1675. BEGIN
  1676.   installed := watch >= 0;
  1677.   active    := isWatch;
  1678. END isWatchDog;
  1679.  
  1680. VAR hasMxAlloc  : BOOLEAN;
  1681.     i           : CARDINAL;
  1682.     tPtr        : Str255Ptr;
  1683.  
  1684. BEGIN
  1685.   isWatch  := FALSE;
  1686.   watch    := -1;
  1687.   accCount := 1;
  1688.   protoCnt := 1;
  1689.   hasMxAlloc := MagicDOS.Mxalloc ($FFFFFFFF,3) # ADDRESS(-32L);
  1690.   IF multiTask & hasMxAlloc
  1691.   THEN
  1692.     (* Mxalloc: Readable, TT-RAM preferred *)
  1693.     memPtr := MagicDOS.Mxalloc (TSIZE (memDescr), $43);
  1694.   ELSE
  1695.     ALLOCATE (memPtr, TSIZE (memDescr));
  1696.   END;
  1697.   IF memPtr = NIL THEN HALT END;
  1698.   tPtr := CADR (appName);
  1699.   FOR i := 0 TO 49 DO
  1700.     memPtr^.apName[i]   := tPtr^[i];
  1701.   END;
  1702. END Protokoll.
  1703.